﻿//---------------------
// 数独的递归解密程序
// :> --Alex
//---------------------
//留言：
//由于基本没有优化，虽然计算时长平均在一两分钟内，但遇到过特殊情况最久的可能要来到10min不止。。。
//其实递归刚开始写的时候一直一知半解，但是每多写几条，每多看看返回的结果也就能渐渐理解了，所以大家也可以试着写写hh
//我想我的交互架构可能还是有点问题，goto写的太多了
//如果在交互（输入）系统上有奇怪的bug就算了 ; _ ; ,这类的真不想修和测，当然太严重还是要修的
// 
//优化：
//比较大的问题是对于较深，起始节点解较大的数独运算时长和所需的栈的要求很高，后续有空试试算法优化
//我想流式输入可以优化为可从指定位置开始，
//另外我想格式化输入的处理（包括错误返回，逻辑处理）可以优化并封装
//另外如果运用底层机械码可能能简化不少数据判断与处理
//嗯，我想递归不是最优解，后面可以试试迭代
// 
// 感谢：
// 感谢yisama的热情测试:>
//---------------------
#include<windows.h>
#include <stdio.h>
#include<string.h>
#include <time.h>

struct Point
{
	bool title;  //是否为题目
	bool show;	 //答案是否展示
	int num;	 //当前点的值
};

//迭代--------------------------------
int stringLong = 1;				//答案容器的大小
struct Point(*answerCon)[81];	//答案容器

long long int count = 0;		//递归次数
int diffAnswer = 0;				//当前解的数量
bool haveAnswer = false;		//有解时的开关
bool end = false;				//终止
bool countInf = false;			//计算时是否提供详细信息
//------------------------------------
int random(int limit);								//随机数
void color(int color);								//颜色
char* GetString();									//输入获取
void map_print(Point* sit);							//打印
void Love(int num, int seat, Point* map);			//核心递归
bool RightCheck(int num, int seat, Point* map);		//数独规则检测

int main()
{

	//for (int i = 0 ; i < 81 ; i++) {
	//	map[i].num = i;
	//}

	printf(" 欢迎使用数独工具\n hanks for you use the sudoku tool\n");

	srand(time(NULL));

	while (1) {
		Point map[81]{ };
		for (int i = 0; i < 81; i++)
			map[i].show = true;
		//输入框架
		while (1) {
			printf("[0]输入（修改）题目（坐标-最准确）\n[1]输入题目（光标-最直观（未制作））\n[2]输入题目（串式-最快速）\n>>>");
			char* con = GetString();
			if (con[0] == '0') {//坐标
				free(con);
				while (1) {
					map_print(map);
					//格式化输入系统
					//输入样式---------------
					//(1,9)->1;(0,1)->6...
					//-----------------------
					printf("请按格式填入题目提供的数\n输入样式(x:行；y:列；z:对应的数)(z = 0 : 擦除此数)：(x,y)z;\n[0]切换输入方式\n>>>");
					int x = -1;
					int y = -1;
					bool xCheck = false;
					bool yCheck = false;
					bool zCheck = false;
					bool errorCheck = false;
					char error[100] = { };
					int errorNum = 0;
					char* input = GetString();
					if (input[0] == '0') {
						free(input);
						goto change;
					}
					for (int i = 0; i < strlen(input); i++) {
						//printf("\n%d\n", sizeof(input) / sizeof(char));

						//printf("\n%d %d %d\n",errorNum,i, strlen(input));


						if (input[i] == ' ' || input[i] == '-' || input[i] == '>' || input[i] == '.') {//略过的字符

							//错误信息处理
							if (errorCheck)
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];

							continue;
						}

						//数据提取
						if (xCheck) {
							if (input[i] >= '0' && input[i] <= '8') {
								xCheck = false;
								x = input[i] - 48;
								continue;
							}
							else {
								//printf("\n%c\n",input[i]);
								x = -1;
								y = -1;
								xCheck = false;
								errorCheck = true;
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
								continue;
							}
						}
						else if (yCheck) {
							if (input[i] >= '0' && input[i] <= '8') {
								yCheck = false;
								y = input[i] - 48;
								continue;
							}
							else {
								printf("\n%d", y);
								x = -1;
								y = -1;
								yCheck = false;
								errorCheck = true;
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
								continue;
							}
						}
						else if (zCheck) {
							if (input[i] >= '0' && input[i] <= '9') {
								zCheck = false;
								if (x != -1 && y != -1) {
									map[y * 9 + x].num = input[i] - 48;
									if (input[i] != 0)
										map[y * 9 + x].title = true;
									else
										map[y * 9 + x].title = false;
								}
								continue;
							}
							else {
								x = -1;
								y = -1;
								zCheck = false;
								errorCheck = true;
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
								continue;
							}
						}

						//格式化识别输入并提取数据

						else if (input[i] == '(') {//用于识别第一个数据的字符
							if (errorCheck) {
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
								errorCheck = false;
							}
							xCheck = true;
							continue;
						}
						else if (input[i] == ',') {//用于识别第二个数据的字符

							//错误信息处理
							if (errorCheck)
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
							else
								yCheck = true;
							continue;
						}
						else if (input[i] == ')') {//用于识别第三个数据的字符

							//错误信息处理
							if (errorCheck)
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
							else
								zCheck = true;
							continue;
						}
						else if (input[i] == ';') {//结束一单元格式的识别字符

							//错误信息处理
							if (errorCheck)
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];

							continue;
						}
						else {
							x = -1;
							y = -1;
							xCheck = false;
							yCheck = false;
							zCheck = false;
							errorCheck = true;
							error[errorNum >= 100 ? 99 : errorNum++] = input[i];
							continue;
						}

					}
					free(input);
					while (1) {
						map_print(map);
						//错误信息打印
						if (errorNum > 0)
							printf("输入中有错误信息：%s\n", error);
						
						printf("[0]继续输入（修改）题目\n[1]结束输入并开始计算答案（显示答案与计算过程）\n[2]结束输入并开始计算答案（不直接显示答案）\n>>>");
						char* input2 = GetString();
						if (input2[0] == '0') {
							free(input2);
							break;
						}
						else if (input2[0] == '1') {
							free(input2);
							countInf = true;
							goto end;
						}
						else if (input2[0] == '2') {
							free(input2);
							countInf = false;
							goto end;
						}
						else {
							continue;
						}
					}

				}
			}
			else if (con[0] == '1') {//光标--暂时先不做
				free(con);

			}
			else if (con[0] == '2') {//串式
				free(con);
				while (1) {
					map_print(map);
					//输入样式---------------
					//145 98 6...(共输入81个字符，严格按照数独格子排列下来)
					//-----------------------
					printf("请连续输入81个字符以对应数独中的数，其中用“ ”（空格）代表一个空位\n[0]切换输入方式\n>>>");
					bool errorCheck = false;
					int errorNum = 0;
					char error[100] = { };
					char* input = GetString();
					if (input[0] == '0') {
						free(input);
						goto change;
					}
					for (int i = 0; i < strlen(input); i++) {
						if (i >= 81)
							errorCheck = true;
						if (errorCheck) {
							error[errorNum >= 100 ? 99 : errorNum++] = input[i];
							continue;
						}
						if ((input[i] >= '1' && input[i] <= '9') || input[i] == ' ') {
							map[i].num = input[i] == ' ' ? 0 : input[i] - '0';
							map[i].title = input[i] == ' ' ? false : true;
						}
						else {
							for (int i = 0; i < 81; i++) {
								map[i].num = 0;
								map[i].title = false;
							}
							errorCheck = true;
						}
					}
					free(input);
					while (1) {
						map_print(map);
						if (errorNum > 0)
							printf("输入中有错误信息：%s\n", error);
						printf("[0]继续输入（修改）题目\n[1]结束输入并开始计算答案（显示答案与计算过程）\n[2]结束输入并开始计算答案（不直接显示答案）\n>>>");
						char* input2 = GetString();
						if (input2[0] == '0') {
							free(input2);
							break;
						}
						else if (input2[0] == '1') {
							free(input2);
							countInf = true;
							goto end;
						}
						else if (input2[0] == '2') {
							free(input2);
							countInf = false;
							goto end;
						}
						else {
							continue;
						}
					}

				}
			}
			else {
			//结束输入，进入下一阶段
			end:

				//检测题目是否正常
				for (int i = 0; i < 81; i++) {
					printf("\n!%d %d", i, map[i].num);
					if (map[i].num != 0) {
						if (!RightCheck(map[i].num, i, map)) {
							printf("\n?%d", RightCheck(map[i].num, i, map));
							while (1) {
								printf("\n你输入的题目存在问题\n[0]修改输入\n[1]重新输入\n[2]退出程序\n>>>");
								char* input2 = GetString();
								if (input2[0] == '0') {
									free(input2);
									goto change;
								}
								else if (input2[0] == '1') {
									free(input2);
									goto back3;
								}
								else if (input2[0] == '2') {
									free(input2);
									exit(0);
								}
								else {
									continue;
								}
							}
						}
					}
				}
				break;
			}
		//继续输入
		change:;
		}

		//结果计算--------------------------------------
		//初始化
		count = 0;
		diffAnswer = 0;
		haveAnswer = false;
		end = false;
		stringLong = 1;
		answerCon = (Point(*)[81])calloc(stringLong, sizeof(Point[81]));

		//计算与打印
		Love(1, 0, map);
		map_print(map);
		printf("\n运算结束，共 %d 种情况", diffAnswer);
		//----------------------------------------------
		
		//答案处理
		while (1) {
			int kind = -1;
			printf("\n[0]（全部答案）打印所有情况的答案\n[1]（单一答案）选择性打印指定情况答案\n[2]（指定提示）获取指定情况答案的指定位置的值\n[3]（随机提示）获取指定情况答案的随机位置的值\n[4]将解与答案匹配\n[5]输入新题目\n[6]退出程序\n>>>");//后续添加玩家输入解与答案匹配的功能
			char* input = GetString();
			//printf("\n%d",input[0] - '0');
			switch (input[0] - '0')
			{
			case 0:
				free(input);
				for (int i = 0; i < stringLong; i++) {
					printf("\n情况 %d ：", i + 1);
					for (int a = 0; a < 81; a++)
						answerCon[i][a].show = true;
					map_print(answerCon[i]);
				}
				break;
			case 1:
				free(input);
				while (1) {//情况选择
					printf("\n选择情况:[%d]-[%d]\n[0]退出当前模式\n>>>", 1, stringLong);
					char* inputStr = GetString();
					if (inputStr[0] == '0') {
						goto back;
					}
					int input = inputStr[1] < '0' || inputStr[1] > '9' ? (inputStr[0] - '0') : (inputStr[0] - '0') * 10 + (inputStr[1] - '0');
					//printf("\n%d %d %d", input , inputStr[0] - '0', inputStr[1] - '0');
					free(inputStr);
					if (input >= 1 && input <= stringLong) {
						for (int i = 0; i < 81; i++)
							answerCon[input - 1][i].show = true;
						map_print(answerCon[input - 1]);
					}
					else {
						continue;
					}
				}
				break;
			case 2:
				free(input);

				while (1) {//情况选择
					printf("\n选择情况:[%d]-[%d]\n>>>", 1, stringLong);
					char* inputStr = GetString();
					int input = inputStr[1] < '0' || inputStr[1] > '9' ? (inputStr[0] - '0') : (inputStr[0] - '0') * 10 + (inputStr[1] - '0');
					free(inputStr);
					if (input >= 1 && input <= stringLong) {
						kind = input - 1;
						break;
					}
					else {
						continue;
					}
				}

				while (1) {
					printf("请按格式填入需要提示的数\n输入样式(x:行；y:列)：(x,y);\n[0]退出当前模式\n>>>");
					int x = -1;
					int y = -1;
					bool xCheck = false;
					bool yCheck = false;
					bool errorCheck = false;
					char error[100] = { };
					int errorNum = 0;
					char* input = GetString();
					if (input[0] == '0') {
						free(input);
						goto back;
					}
					for (int i = 0; i < strlen(input); i++) {
						//printf("\n%d\n", sizeof(input) / sizeof(char));

						//printf("\n%d %d %d\n",errorNum,i, strlen(input));

						if (input[i] == ' ' || input[i] == '-' || input[i] == '>' || input[i] == '.') {//略过的字符

							//错误信息处理
							if (errorCheck)
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];

							continue;
						}

						//数据提取
						if (xCheck) {
							if (input[i] >= '0' && input[i] <= '8') {
								xCheck = false;
								x = input[i] - 48;
								continue;
							}
							else {
								//printf("\n%c\n",input[i]);
								x = -1;
								y = -1;
								xCheck = false;
								errorCheck = true;
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
								continue;
							}
						}
						else if (yCheck) {
							if (input[i] >= '0' && input[i] <= '8') {
								yCheck = false;
								y = input[i] - 48;
								continue;
							}
							else {
								x = -1;
								y = -1;
								yCheck = false;
								errorCheck = true;
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
								continue;
							}
						}

						//格式化识别输入并提取数据

						if (input[i] == '(') {//用于识别第一个数据的字符
							if (errorCheck) {
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
								errorCheck = false;
							}
							xCheck = true;
							continue;
						}
						else if (input[i] == ',') {//用于识别第二个数据的字符

							//错误信息处理
							if (errorCheck)
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];
							else
								yCheck = true;
							continue;
						}
						else if (input[i] == ')') {//用于识别开启字符
							if (x != -1 && y != -1) {
								if (!answerCon[kind][y * 9 + x].title)
									answerCon[kind][y * 9 + x].show = true;
							}
						}
						else if (input[i] == ';') {//结束一单元格式的识别字符

							//错误信息处理
							if (errorCheck)
								error[errorNum >= 100 ? 99 : errorNum++] = input[i];

							continue;
						}
						else {
							x = -1;
							y = -1;
							xCheck = false;
							yCheck = false;
							errorCheck = true;
							error[errorNum >= 100 ? 99 : errorNum++] = input[i];
							continue;
						}
					}
					free(input);
					if (errorNum > 0)
						printf("输入中有错误信息：%s\n", error);
					printf("情况 %d:", kind + 1);
					map_print(answerCon[kind]);
				}
				break;
			case 3:
				free(input);

				while (1) {//情况选择
					printf("\n选择情况（[%d-%d]）\n>>>", 1, stringLong);
					char* inputStr = GetString();
					int input = inputStr[1] < '0' || inputStr[1] > '9' ? (inputStr[0] - '0') : (inputStr[0] - '0') * 10 + (inputStr[1] - '0');
					free(inputStr);
					if (input >= 1 && input <= stringLong) {
						kind = input - 1;
						break;
					}
					else {
						continue;
					}
				}

				while (1) {
					int i = 0;
					while (1) {
						int ranNum = random(81);
						if (answerCon[kind][ranNum].title || answerCon[kind][ranNum].show) {
							i++;
							if (i > 81) {
								printf("\n已全部显示");
								goto back;
							}
							continue;
						}
						answerCon[kind][ranNum].show = true;
						printf("情况 %d:", kind + 1);
						map_print(answerCon[kind]);
						break;
					}
					while (1) {
						printf("[0]下一个提示\n[1]退出\n>>>");
						char* input = GetString();
						if (input[0] == '0');
						else if (input[0] == '1')
							goto back;
						else
							continue;
						break;
					}
				}
				break;
			case 4:
				free(input);
				break;
			case 5:
				free(input);
				//printf("1*");
				goto back2;
				break;
			case 6:
				free(input);
				free(answerCon);
				exit(0);
				break;
			default:
				break;
			}
		//返回答案显示
		back:
			for (int i = 0; i < 81; i++) {
				if (!map[i].title) {
					map[i].show = false;
					map[i].num = 0;
				}
			}
			//break;
		}

	//重启程序
	back2:
		//printf("2*");
		free(answerCon);
		//map_print(map);
		//RightCheck(-1,80,map);
	
	//避免释放空指针的重启（题目输入错误）
	back3:;
	}
}

//❤递归-------------------------------------------------------------------------------------------------------------------------❤
// 基本原理是把每一格的每种情况作为一个节点，下一格的不同情况作为上一格（节点）的分支，可行就继续往下探深，不行就向上回溯节点并继续探深，
//每一次探到底层就作为一个解，当尝试回溯到根节点之后（即第一格的数字9之后）即为递归结束（整体探深历程结束）的标志
//❤-----------------------------------------------------------------------------------------------------------------------------❤
void Love(int num, int seat, Point* map) {
	if (countInf)
		printf("\ncounting...%lld %d %d(%d)", count++, num, seat, diffAnswer);
	else
		printf("\ncounting...%lld (%d)", count++, diffAnswer);

	if (end) {
		return;
	}

	if (seat < 0) {
		end = true;
		return;
	}

	if (haveAnswer) {
		haveAnswer = false;
		for (int i = seat; i < 81; i++) {
			if (!map[i].title) {
				map[i].num = 0;
			}
		}
	}

	if (num > 9 || num == -1) {
		//printf("no");
		if (!map[seat].title)
			map[seat].num = 0;
		Love(map[seat - 1].title ? -1 : map[seat - 1].num + 1, seat - 1, map);
	}

	if (map[seat].title && seat != 80) {
		Love(num, seat + 1, map);
	}
	else if(map[seat].title && seat == 80) {
		for (int a = 0; a < 81; a++) {

			if (diffAnswer == 0) {
				for (int i = 0; i < 81; i++) {
					answerCon[stringLong - 1][i].num = map[i].num;
					if (map[i].title)
						answerCon[stringLong - 1][i].title = true;
					else
						answerCon[stringLong - 1][i].title = false;
					//answerCon[stringLong - 1][i].show = true;
				}
				if (countInf)
					map_print(map);
				diffAnswer++;
				break;
			}
			else {
				if (answerCon[stringLong - 1][a].num == map[a].num) {
					continue;
				}
				answerCon = (Point(*)[81])realloc(answerCon, ++stringLong * sizeof(Point[81]));
				for (int i = 0; i < 81; i++) {
					answerCon[stringLong - 1][i].num = map[i].num;
					if (map[i].title)
						answerCon[stringLong - 1][i].title = true;
					else
						answerCon[stringLong - 1][i].title = false;
					//answerCon[stringLong - 1][i].show = true;
				}
				if (countInf)
					map_print(map);
				//printf("\n?\n");
				diffAnswer++;
				break;
			}
		}

		haveAnswer = true;
		return;

	}

	if (RightCheck(num, seat, map)) {
		if (end) {
			return;
		}
		if (num > 9 || num == -1) {
			//printf("no");
			if (!map[seat].title)
				map[seat].num = 0;
			Love(map[seat - 1].title ? -1 : map[seat - 1].num + 1, seat - 1, map);
		}
		//printf("\ntrue %d", seat);
		if (seat >= 80) {
			map[seat].num = num;

			//答案的记录
			for (int a = 0; a < 81; a++) {
				//for (int i = 0; i < 81 ;i++) {
				//	printf("\n%d|%d", i, answerCon[stringLong - 1][i]);
				//}

				//答案记录
				//printf("\n%d|%d", a, answerCon[stringLong - 1][a]);
				if (diffAnswer == 0) {
					for (int i = 0; i < 81; i++) {
						answerCon[stringLong - 1][i].num = map[i].num;
						if (map[i].title)
							answerCon[stringLong - 1][i].title = true;
						else
							answerCon[stringLong - 1][i].title = false;
						//answerCon[stringLong - 1][i].show = true;
					}
					if (countInf)
						map_print(map);
					diffAnswer++;
					break;
				}
				else {
					if (answerCon[stringLong - 1][a].num == map[a].num) {
						continue;
					}
					answerCon = (Point(*)[81])realloc(answerCon, ++stringLong * sizeof(Point[81]));
					for (int i = 0; i < 81; i++) {
						answerCon[stringLong - 1][i].num = map[i].num;
						if (map[i].title)
							answerCon[stringLong - 1][i].title = true;
						else
							answerCon[stringLong - 1][i].title = false;
						//answerCon[stringLong - 1][i].show = true;
					}
					if (countInf)
						map_print(map);
					//printf("\n?\n");
					diffAnswer++;
					break;
				}
			}

			haveAnswer = true;
			return;
		}
		else {
			map[seat].num = num;
			if (countInf)
				map_print(map);
			Love(1, seat + 1, map);
		}
	}
	else {
		if (num >= 9) {
			if (!map[seat].title)
				map[seat].num = 0;
			Love(map[seat - 1].title ? -1 : map[seat - 1].num + 1, seat - 1, map);
		}
		else {
			Love(num + 1, seat, map);
		}
	}
}

bool RightCheck(int num, int seat, Point* map) {
	//printf("\nhave check:%d %d", num, seat);

	//横向检测
	int xT = seat / 9;
	for (int i = 0; i < 9; i++) {
		if (((xT * 9) + i) == seat)
			continue;
		if (map[(xT * 9) + i].num == num) {
			//printf("\n*1");
			return false;
		}
	}

	//纵向检测
	int yT = seat % 9;
	for (int i = 0; i < 9; i++) {
		if (((i * 9) + yT) == seat)
			continue;
		if (map[(i * 9) + yT].num == num) {
			//printf("\n*2");
			return false;
		}
	}

	//当前小格检测--十字检测，先检测目标十字方向上是否可行并记录，再用记录数据遍历十字对应位的值
	int xP = yT;
	int yP = xT;
	signed int xC[2]{ (xP % 3 ? -(xP % 3) : 1) , (xP % 3 != 2 ? 2 - (xP % 3) : -1) };
	signed int yC[2]{ yP + (yP % 3 ? -(yP % 3) : 1) , yP + (yP % 3 != 2 ? 2 - (yP % 3) : -1) };
	for (int i = 0; i < 2; i++) {
		//printf("\nxC[%d]:%d", i, xC[i] + seat);
		if (map[xC[i] + seat].num == num) {
			//printf("\n*3");
			return false;
		}
	}
	for (int i = 0; i < 2; i++) {
		//printf("\nyC[%d]:%d", i, yC[i] * 9 + xP);
		if (map[yC[i] * 9 + xP].num == num) {
			//printf("\n*4");
			return false;
		}
	}
	for (int x = 0; x < 2; x++) {
		for (int y = 0; y < 2; y++) {
			//printf("\n(%d,%d):%d", yC[y], xC[y] + xP, yC[y] * 9 + xC[x] + xP);
			if (map[yC[y] * 9 + xC[x] + xP].num == num) {
				//printf("\n*5");
				return false;
			}
		}
	}

	//printf("\n*6");
	return true;
}

int random(int limit) {
	int a;
	a = rand() % limit;
	return a;
}

//文本颜色
void color(int color) {
	HANDLE hconsole = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hconsole, color);
}

char* GetString() {
	int stringLong = 1;
	char* stringCon = (char*)malloc(stringLong * sizeof(char));
	char charCon;
	//while ((charCon = getchar()) == '\n');
	while ((charCon = getchar()) != '\n') {
		stringCon[stringLong - 1] = charCon;
		if (stringLong >= 500) {
			free(stringCon);
			printf("ERROR:too long");
			return NULL;
		}
		stringCon = (char*)realloc(stringCon, ++stringLong * sizeof(char));
		if (stringCon == NULL) {
			free(stringCon);
			printf("ERROR:No RAM");
			return NULL;
		}
	}
	stringCon[stringLong - 1] = '\0';
	//char stringBack[] = stringCon;
	return stringCon;
}

//打印
void map_print(Point* seat) {
	/*颜色名称	前景色代码	背景色代码（左移4位）	RGB 近似值
		黑色		0			0					#000000
		深蓝色		1			16					#000080
		深绿色		2			32					#008000
		深青色		3			48					#008080
		深红色		4			64					#800000
		深紫色		5			80					#800080
		深黄色（棕）6			96					#808000
		灰色（默认）7			112					#C0C0C0
		深灰色		8			128					#808080
		亮蓝色		9			144					#0000FF
		亮绿色		10			160					#00FF00
		亮青色		11			176					#00FFFF
		亮红色		12			192					#FF0000
		亮紫色（粉）13			208					#FF00FF
		亮黄色  	14			224					#FFFF00
		白色		15*/

	//自己可以调颜色:>
	int color1 = 6;	//边框
	int color2 = 12;//题目
	int color3 = 7; //作答
	int color4 = 8;//光标

	int n = 0, m = 8;
	printf("\n     0   1   2   3   4   5   6   7   8\n");
	for (int i = 0; i < 9; i++, m += 9) {
		if ((((m + 1) / 9) - 1) % 3 != 0)
			color(color1);
		printf("\n   +");
		color(7);
		for (int i = 0; i < 3; i++) {
			if ((((m + 1) / 9) - 1) % 3 == 0)
				color(color1);
			for (int i = 0; i < 2; i++)
				printf("---+");
			printf("---");
			color(7);

			if ((((m + 1) / 9) - 1) % 3 != 0)
				color(color1);
			printf("+");
			color(7);
		}
		printf("\n %d ", ((m + 1) / 9) - 1);
		color(color1);
		printf("|");
		color(7);

		for (n; n <= m; n++) {
			printf(" ");
			if (seat[n].title)
				color(color2);
			else
				color(color3);

			if (!seat[n].num || (!seat[n].show && !seat[n].title))
				printf(" ");
			else
				printf("%d", seat[n].num);
			if ((n + 1) % 3 == 0)
				color(color1);
			else
				color(7);
			printf(" |");
			color(7);
		}
	}
	if ((((m + 1) / 9) - 1) % 3 != 0)
		color(color1);
	printf("\n   +");
	color(7);

	for (int i = 0; i < 3; i++) {
		color(color1);
		for (int i = 0; i < 2; i++)
			printf("---+");
		printf("---");
		color(7);
		printf("+");
	}
	printf("\n");
	color(7);
}
